package com.example.demo.service.impl;
import com.example.demo.exception.LibraryException;
import com.example.demo.mapper.BookMapper;
import com.example.demo.mapper.UserBookMapper;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.Book;
import com.example.demo.model.User;
import com.example.demo.service.LibraryService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.Objects;

@Service
public class LibraryServiceImpl implements LibraryService {

   private final UserMapper userMapper;
   private final BookMapper bookMapper;
   private final UserBookMapper userBookMapper;

   public LibraryServiceImpl(
           UserMapper userMapper,
           BookMapper bookMapper,
           UserBookMapper userBookMapper) {
      this.userMapper = Objects.requireNonNull(userMapper);
      this.bookMapper = Objects.requireNonNull(bookMapper);
      this.userBookMapper = Objects.requireNonNull(userBookMapper);
   }

   @Override
   public User findUserById(Long userId) throws LibraryException {
      User user = userMapper.findUserById(userId);
      if (user == null) {
         throw new LibraryException(404,"USER_NOT_FOUND", "用户不存在");
      }
      return user;
   }

   @Override
   public Book findBookById(Long bookId) throws LibraryException {
      Book book = bookMapper.findBookById(bookId);
      if (book == null) {
         throw new LibraryException(404,"BOOK_NOT_FOUND", "书籍不存在");
      }
      return book;
   }

   @Override
   @Transactional
   public void borrowBook(User user, Book book) throws LibraryException {
      if (!"AVAILABLE".equals(book.getStatus())) {
         throw new LibraryException(404,"BOOK_UNAVAILABLE", "书籍不可借阅");
      }
      if (book.getStock() <= 0) {
         throw new LibraryException(404,"BOOK_OUT_OF_STOCK", "书籍库存不足");
      }

      int affectedRows = bookMapper.borrowBookWithLock(book.getBookId());
      if (affectedRows == 0) {
         throw new LibraryException(404,"CONCURRENT_ERROR", "并发操作冲突，请重试");
      }

      userBookMapper.insertBorrowRecord(user.getUserId(), book.getBookId());
   }


   @Override
   @Transactional
   public double returnBook(User user, Book book, int overdueDays) throws LibraryException {
      if (!userBookMapper.existsBorrowRecord(user.getUserId(), book.getBookId())) {
         throw new LibraryException(404,"BOOK_NOT_BORROWED", "未借阅此书");
      }

      bookMapper.returnBook(book.getBookId());
      userBookMapper.deleteBorrowRecord(user.getUserId(), book.getBookId());

      return Math.max(0, overdueDays * 1.0);
   }

   @Override
   public void addWaitingUser(Book book, User user) throws LibraryException {
      if (userBookMapper.existsBorrowRecord(user.getUserId(), book.getBookId())) {
         throw new LibraryException(404,"USER_ALREADY_IN_QUEUE", "用户已在等待队列中");
      }
      userBookMapper.insertBorrowRecord(user.getUserId(), book.getBookId());
   }
   @Override
   @Transactional
   public void borrowBookById(Long userId, Long bookId) throws LibraryException {
      User user = findUserById(userId);
      Book book = findBookById(bookId);
      borrowBook(user, book);
   }

}